
package provide helpbrowser 0.1

namespace eval ::helpbrowser:: {
    variable help_top_directory ""

    namespace export open_helpbrowser
}


################## help browser and support functions #########################
proc ::helpbrowser::open_helpbrowser {} {
    variable help_top_directory
    if {![file isdirectory $help_top_directory]} {
        pdtk_post "ERROR: menu_doc_browser non-directory $help_top_directory\n"
    }
    if { [winfo exists .help_browser.frame] } {
        wm deiconify .help_browser
        raise .help_browser
    } else {
        toplevel .help_browser -class HelpBrowser
        wm group .help_browser .
        wm transient .help_browser
        wm title .help_browser [_ "Help Browser"]
        .help_browser configure -menu $::dialog_menubar
        ::pd_bindings::window_bindings .help_browser
        bind .help_browser <$::modifier-Key-w> "wm withdraw .help_browser"

        wm resizable .help_browser 0 0
        frame .help_browser.frame
        pack .help_browser.frame -side top -fill both
        doc_make_listbox .help_browser.frame $::sys_libdir/doc 0
    }
}

proc ::helpbrowser::doc_make_listbox {base dir count} {
    # check for [file readable]?
	# requires Tcl 8.5 but probably deals with special chars better:
	#        destroy {*}[lrange [winfo children $base] [expr {2 * $count}] end]
	if { [catch { eval destroy [lrange [winfo children $base] \
									[expr { 2 * $count }] end] } errorMessage] } {
		pdtk_post "doc_make_listbox: error listing $dir\n"
	}
    # exportselection 0 looks good, but selection gets easily out-of-sync
	set current_listbox [listbox "[set b "$base.listbox$count"]-list" -yscrollcommand \
							 [list "$b-scroll" set] -height 20 -width 22 -exportselection 0]
	pack $current_listbox [scrollbar "$b-scroll" -command [list $current_listbox yview]] \
		-side left -expand 1 -fill y -anchor w
	foreach item [concat [lsort -dictionary [glob -directory $dir -nocomplain -types {d} -- *]] \
					  [lsort -dictionary [glob -directory $dir -nocomplain -types {f} -- \
											  *.{pd,pat,mxb,mxt,txt,htm,html}]]]  {
		$current_listbox insert end "[file tail $item][expr {[file isdirectory $item] ? {/} : {}}]"
	}
	bind $current_listbox <Button-1> \
        [list ::helpbrowser::doc_navigate $dir $count %W %x %y]
	bind $current_listbox <Double-Button-1> \
        [list ::helpbrowser::doc_double_button $dir $count %W %x %y]
}

proc ::helpbrowser::doc_navigate {dir count width x y} {
    if {[set newdir [$width get [$width index "@$x,$y"]]] eq {}} {
        return
    }
    set dir_to_open [file join $dir $newdir]
    if {[file isdirectory $dir_to_open]} {
        doc_make_listbox [winfo parent $width] $dir_to_open [incr count]
    }
}

proc ::helpbrowser::doc_double_button {dir count width x y} {
    if {[set newdir [$width get [$width index "@$x,$y"]]] eq {}} {
        return
    }
    set dir_to_open [file join $dir $newdir]
    if {[file isdirectory $dir_to_open]} {
        doc_navigate $dir $count $width $x $y
    } else {
        regsub -- $::sys_libdir [file dirname $dir_to_open] "" subdir
        set file [file tail $dir_to_open]
        if { [catch {menu_doc_open $subdir $file} fid] } {
            puts stderr "Could not open $sys_libdir/$subdir/$file\n"
        }
        return; 
    }
}
